package img

import (
	"errors"
	"fmt"
	"gpt-api/framework/codes"
	"gpt-api/framework/cos"
	"gpt-api/framework/db"
	"gpt-api/framework/did"
	"gpt-api/framework/ginplus"
	"gpt-api/pkg/model"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
)

type Handler struct {
	db  *db.DB
	did *did.DID
}

func New(db *db.DB) *Handler {
	return &Handler{db: db}
}

// ImgProcess
func (h *Handler) ImgProcess(c *gin.Context) error {
	userId := ginplus.GetUserID(c)
	if userId <= 0 {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("用户id错误，请重新登录。"))
	}

	// 获取用户信息
	userInfo, err := (&model.Users{}).GetUserInfoById(h.db, userId)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	// 获取用户的root member info
	// MemberRoot, err := (&model.Member{}).GetMemberRootByUserId(h.db, userId)
	// if err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	// checkout is vip?
	// userId := ginplus.GetUserID(c)

	// userInfo, err := (&model.Users{}).GetUserInfoById(h.db, userId)

	// if err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	// if userInfo.VipLevel == 0 {
	// 	return ginplus.ReplyError(c, codes.UserNotVip, errors.New("user not vip"))
	// }

	// if time.Now().After(userInfo.Expired) {
	// 	return ginplus.ReplyError(c, codes.UserVipEexpired, errors.New("user vip expired"))
	// }

	// upload to tencent cos
	// uploadImgPath, err := cos.Upload(c, viper.GetString("FileUploadSetting.CosPictureSavePath"))
	// if err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	r, uploadCosImgPath := cos.Upload(c, viper.GetString("FileUploadSetting.CosPictureSavePath"))

	if !r {
		return ginplus.ReplyInternalError(c, errors.New("local upload img to cos error"))
	}

	//

	var ty string
	var scoreTake int = 0
	if c.PostForm("t") == "2" {
		// 上色
		scoreTake = viper.GetInt("score.colorfulTake")
		// if userInfo.Score < scoreTake {
		// 	return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("user score not enough"))
		// }
		ty = "color"
	} else if c.PostForm("t") == "3" {
		// 裁剪
		ty = "cropped"
	} else {
		// 增强
		scoreTake = viper.GetInt("score.enhanceTake")
		// if userInfo.Score < scoreTake {
		// 	return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("user score not enough"))
		// }
		ty = "final"
	}

	// fmt.Println(ty)

	// process img
	didLocalImgSlice, err := h.did.BeatefulImg(c, ty)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	var result []string
	// var sourceIds []uint64
	var t int = 1
	if c.PostForm("t") == "2" {
		t = model.UserImageSourceTypeColor
	} else if c.PostForm("t") == "3" {
		t = model.UserImageSourceTypeSlice
	} else {
		t = model.UserImageSourceTypeEnhance
	}
	handleId := (&model.UserImage{}).GenerateHandleId()
	// upload to tencent cos
	for _, didLocalImgPath := range didLocalImgSlice {

		re, didCosImgPath := cos.UploadLocalFile(didLocalImgPath, viper.GetString("FileUploadSetting.CosPictureSavePath"))
		if !re {
			return ginplus.ReplyInternalError(c, errors.New("did upload img to cos error"))
		}
		// 保存到user image表
		userImage := model.UserImage{
			UserId:     uint(userInfo.ID),
			ImgUrl:     didCosImgPath,
			SourceType: t,
			HandleId:   handleId,
			MediaType:  model.UserImageMediaTypeImage,
		}
		if err := userImage.Create(h.db); err != nil {
			return ginplus.ReplyInternalError(c, err)
		}

		// 保存到member image表
		// memberImage := model.MemberImage{
		// 	UserID:   userInfo.ID,
		// 	MemberID: uint(MemberRoot.ID),
		// 	ImageUrl: didCosImgPath,
		// 	Type:     1,
		// }
		// if err := memberImage.Create(h.db); err != nil {
		// 	return ginplus.ReplyInternalError(c, err)
		// }
		// sourceIds = append(sourceIds, userImage.ID)
		result = append(result, didCosImgPath)
	}

	// if ty == "final" {
	// 	// 扣除用户积分
	// 	err := (&model.Score{}).EnhanceTake(h.db, uint(userInfo.ID))
	// 	if err != nil {
	// 		return ginplus.ReplyInternalError(c, err)
	// 	}
	// }

	// if ty == "restored" {
	// 	// 扣除用户积分
	// 	err := (&model.Score{}).ColorfulTake(h.db, uint(userInfo.ID))
	// 	if err != nil {
	// 		return ginplus.ReplyInternalError(c, err)
	// 	}
	// }

	return ginplus.ReplyJSON(c, gin.H{
		"didCosImgPath":    result,
		"uploadCosImgPath": uploadCosImgPath,
		"score":            scoreTake,
		"handleId":         handleId,
	})

}

func (h *Handler) SourceSave(c *gin.Context) error {
	userId := ginplus.GetUserID(c)
	if userId <= 0 {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("用户id错误，请重新登录。"))
	}

	var req struct {
		HandleId string `json:"handle_id" binding:"required"`
	}

	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	fmt.Println(req.HandleId)
	// 通过handle_id获取用户的图片或者视频信息
	userImages, err := (&model.UserImage{}).GetSourceByHandleId(h.db, req.HandleId)
	if err != nil {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("资源未找到，请重试。"))
	}

	// 检查资源的第一个是否属于用户
	if userImages[0].UserId != uint(userId) {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("您的权限不足，请重试。"))
	}

	// 根据第一个资源的SourceType判断是什么类型的资源
	var scoreTake int
	if userImages[0].SourceType == model.UserImageSourceTypeColor {
		// 上色
		scoreTake = viper.GetInt("score.colorfulTake")
		// 消费积分
		err := (&model.Score{}).ColorfulTake(h.db, uint(userId))
		if err != nil {
			return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("用户积分不足，请充值。"))
		}
	} else if userImages[0].SourceType == model.UserImageSourceTypeSlice {
		// 裁剪和视频
		scoreTake = viper.GetInt("score.videoTake")
		// 消费积分
		err := (&model.Score{}).VideoTake(h.db, uint(userId))
		if err != nil {
			return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("用户积分不足，请充值。"))
		}
	} else {
		// 增强
		scoreTake = viper.GetInt("score.enhanceTake")
		// 消费积分
		err := (&model.Score{}).EnhanceTake(h.db, uint(userId))
		if err != nil {
			return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("用户积分不足，请充值。"))
		}
	}

	// 检查用户积分是否足够
	userInfo, err := (&model.Users{}).GetUserInfoById(h.db, userId)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	if userInfo.Score < scoreTake {
		return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("用户积分不足，请充值。"))
	}

	// 获取用户的root member info
	MemberRoot, err := (&model.Member{}).GetMemberRootByUserId(h.db, userId)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	// 保存到member image表
	for _, userImage := range userImages {
		memberImage := model.MemberImage{
			UserID:   uint64(userId),
			MemberID: uint(MemberRoot.ID),
			ImageUrl: userImage.ImgUrl,
			Type:     int8(userImage.MediaType),
		}
		if _, err := memberImage.Create(h.db); err != nil {
			return ginplus.ReplyInternalError(c, err)
		}
	}

	return ginplus.ReplyJSON(c, gin.H{
		"score":     scoreTake,
		"handle_id": req.HandleId,
	})
}

func (h *Handler) SourceDel(c *gin.Context) error {
	userId := ginplus.GetUserID(c)
	if userId <= 0 {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("用户id错误，请重新登录。"))
	}

	var req struct {
		HandleId string `form:"handle_id" binding:"required"`
	}

	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	if req.HandleId == "" {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("请传入handle_id"))
	}

	// 获取用户的资源信息
	SourceInfos, err := (&model.UserImage{}).GetSourceByHandleId(h.db, req.HandleId)
	if err != nil {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("资源未找到，请重试。"))
	}

	// 检查资源的第一个是否属于用户
	if SourceInfos[0].UserId != uint(userId) {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("您的权限不足，请重试。"))
	}

	// 删除资源
	for _, SourceInfo := range SourceInfos {
		if err := SourceInfo.Delete(h.db); err != nil {
			return ginplus.ReplyInternalError(c, err)
		}
	}

	return ginplus.ReplyJSON(c, gin.H{
		"code": 0,
		"msg":  "success",
	})
}

// ImgToVideo
func (h *Handler) ImgToVideo(c *gin.Context) error {
	// 获取用户id
	userId := ginplus.GetUserID(c)

	// 获取用户信息
	userInfo, err := (&model.Users{}).GetUserInfoById(h.db, userId)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	// 获取用户的root member info
	// MemberRoot, err := (&model.Member{}).GetMemberRootByUserId(h.db, userId)
	// if err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	var req struct {
		Path string `json:"path"`
		T    int    `json:"t"`
	}

	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	// 获取消耗积分
	scoreTake := viper.GetInt("score.videoTake")

	// 检查用户积分是否足够
	// if userInfo.Score < scoreTake {
	// 	return ginplus.ReplyError(c, codes.UserScoreNotEnough, errors.New("user score not enough"))
	// }

	// 检查path是否存在
	if req.Path == "" {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("路径为空，请重试"))
	}

	// 根据path和用户id获取图片信息
	userImage, err := (&model.UserImage{}).GetImageByUserIdAndPath(h.db, userInfo.ID, req.Path)

	if err != nil {
		return ginplus.ReplyError(c, codes.InvalidParams, errors.New("未找到图片信息，请重试"))
	}

	// 根据path获取图片信息
	// userImage, err := (&model.MemberImage{}).GetMemberImageByPath(h.db, req.Path)
	// if err != nil {
	// 	return ginplus.ReplyError(c, codes.InvalidParams, errors.New("user image not found"))
	// }

	// if userImage.UserID != userInfo.ID {
	// 	return ginplus.ReplyError(c, codes.InvalidParams, errors.New("user image not belong to user"))
	// }

	// 限制上传图片大小
	//c.Request.ParseMultipartForm(2 << 20)

	// 校验c.FormData('t')是否存在 并且是1-10的数字
	it := req.T
	if it == 0 || it < 1 || it > 10 {
		it = 1
	}

	// 把t转成int
	// it, err := strconv.Atoi(t)
	// if err != nil {
	// 	return ginplus.ReplyError(c, codes.InvalidParams, errors.New("t is convert to int error"))
	// }

	// 先把图片上传到cos
	// r, imgCosPath := cos.UploadImg(c, viper.GetString("FileUploadSetting.CosPictureSavePath"))
	// if !r {
	// 	return ginplus.ReplyInternalError(c, errors.New("local upload img to cos error"))
	//}

	// 先进行图片增强并头部裁剪
	// restoredPath, err := h.did.BeatefulImg2(c, "restored")
	// fmt.Println(restoredPath)
	// if err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	// 把图片从cos下载到本地
	imgLocalPath, err := cos.GetCosFile(userImage.ImgUrl)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	// 上传图片到did生成视频
	videoPath, err := h.did.LocalImgToVideo(imgLocalPath, it)
	fmt.Println(videoPath)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	// 上传视频到cos
	re, videoCosPath := cos.UploadLocalFile(videoPath, viper.GetString("FileUploadSetting.CosVideoSavePath"))
	if !re {
		return ginplus.ReplyInternalError(c, errors.New("did upload video to cos error"))
	}

	// 保存到user imgage表
	newUserImage := model.UserImage{
		UserId:     uint(userInfo.ID),
		ImgUrl:     videoCosPath,
		SourceType: model.UserImageSourceTypeSlice,
		HandleId:   userImage.HandleId,
		MediaType:  model.UserImageMediaTypeVideo,
	}
	if err := newUserImage.Create(h.db); err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	// // 保存到user video表
	// userVideo := model.UserVideo{
	// 	UserId:   uint(userInfo.ID),
	// 	VideoUrl: videoCosPath,
	// }
	// if err := userVideo.Create(h.db); err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	// 保存到member image表
	// memberImage := model.MemberImage{
	// 	UserID:   userInfo.ID,
	// 	MemberID: uint(MemberRoot.ID),
	// 	ImageUrl: videoCosPath,
	// 	Type:     2,
	// }
	// if err := memberImage.Create(h.db); err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	// 扣除用户积分
	// err = (&model.Score{}).VideoTake(h.db, uint(userInfo.ID))
	// if err != nil {
	// 	return ginplus.ReplyInternalError(c, err)
	// }

	// 清除本地图片和视频
	os.Remove(imgLocalPath)

	return ginplus.ReplyJSON(c, gin.H{
		"didCosVideoPath": videoCosPath,
		"handleId":        userImage.HandleId,
		"score":           scoreTake,
	})
}
